from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from users.models import UsersModel
import re
from django_redis import get_redis_connection
class CoustomTokenObtainPairSerializer(TokenObtainPairSerializer):

    @classmethod
    def get_token(cls, user):
        # 根据用户，获取token
        token = super().get_token(user)

        token['username'] = user.username
        token['avatar'] = str(user.avatar)
        token['money'] = str(user.money)
        token['credit'] = str(user.credit)
        return token

class RegisterSerializer(serializers.ModelSerializer):
    # 仅在反序列化过程中使用
    re_password = serializers.CharField(required=True,write_only=True,max_length=16,min_length=6)
    sms_code = serializers.CharField(required=True,write_only=True)
    # 仅在序列化使用，注册成功后，返回用户登录令牌：token和refresh两个token
    token = serializers.CharField(read_only=True)
    refresh = serializers.CharField(read_only=True)
    class Meta:
        model = UsersModel
        fields = ['mobile','password','re_password','sms_code','refresh','token']
        # exclued = ['id','username'](除以上字段其它字段全要)
        # 给模型类属性，添加额外的约束条件
        extra_kwargs = {
            "mobile":{
                "required":True,
                "write_only":True
            },
            "password":{
                "required":True,
                "write_only":True,
                "max_length":16,
                "min_length":6
            }
        }
    def validate(self, attrs):
        # 自定义校验规则
        # 校验传递数据，是否满足业务需求
        mobile = attrs.get('mobile',None)
        # 判断手机号是否满足规则、
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            raise serializers.ValidationError(detail='手机号格式错误',code='mobile')
        print('---手机号校验通过-----')
        password = attrs.get("password")
        re_password = attrs.get("re_password")
        if password != re_password:
            raise serializers.ValidationError(detail="两次密码不一致，请重新输入",code="password")
        print('-----密码校验通过------')
        # 验证码校验---开始----
        sms_code = attrs.get('sms_code')
        redis = get_redis_connection('sms_code')
        code = redis.get(f'sms_{mobile}')
        print('打印redis中code----')
        print(code)
        if code == None:
            raise serializers.ValidationError(detail="验证码过期",code="sms_code")
        # 从redis中获取验证码，与前端传递验证码对比
        if code.decode() != sms_code:
            raise serializers.ValidationError(detail="验证码错误",code="sms_code")
        redis.delete(f'sms_{mobile}')
        try:
            # 用户存在，抛出异常
            UsersModel.objects.get(mobile__exact=mobile)
            raise serializers.ValidationError(detail="用户已存在---",code='mobile')
        except UsersModel.DoesNotExist:
            print('---用户不存在数据库，可以正常执行注册-校验通过')
        # 执行数据库操作
        attrs.pop('re_password')
        attrs.pop('sms_code')
        return attrs
    def create(self, validated_data):
        mobile = validated_data.get('mobile')
        password = validated_data.get('password')
        # 注册新用户，初始化用户信息
        user = UsersModel.objects.create_user(
            mobile = mobile,
            password= password,
            # 应该生成默认用户名
            username= mobile,
            money = 0,
            credit = 0,
            avatar = "avatar/2024/38.jpg",
        )
        # 返回token,refresh
        # 手动签发token
        refresh = CoustomTokenObtainPairSerializer.get_token(user)
        user.refresh = str(refresh)
        user.token = str(refresh.access_token)
        return user












